headerbar: do not show buttons for modals/transients
authorOlivier Fourdan <ofourdan@redhat.com>
Tue, 31 May 2016 13:25:52 +0000 (15:25 +0200)
committerOlivier Fourdan <ofourdan@redhat.com>
Wed, 1 Jun 2016 07:47:23 +0000 (09:47 +0200)
GtkHeadeBar checks the window type hint to determine if the regular
buttons such as menu, maximize or iconify should be visible in the
header bar.

However, an application may very well use a "normal" toplevel window and
set it transient and modal afterwards. In such a case, the iconify
button would remain visible, and the user can hide the window, but being
a modal, the parent window would remain insensitive.

Check for the window type, modality and transient relationship to decide
whether or not the regular toplevel buttons should be visible in the
header bar.

https://bugzilla.gnome.org/show_bug.cgi?id=767052

gtk/gtkheaderbar.c
gtk/gtkwindow.c

index ee7a34cadca6e3141c4bd751df046d04eaf69148..5c5b13a3e2ccebe195abcab5edb704067f154671 100644 (file)
@@ -274,7 +274,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
   gint i, j;
   GMenuModel *menu;
   gboolean shown_by_shell;
-  GdkWindowTypeHint type_hint;
+  gboolean is_sovereign_window;
 
   toplevel = gtk_widget_get_toplevel (widget);
   if (!gtk_widget_is_toplevel (toplevel))
@@ -318,7 +318,9 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
   else
     menu = NULL;
 
-  type_hint = gtk_window_get_type_hint (window);
+  is_sovereign_window = (!gtk_window_get_modal (window) &&
+                          gtk_window_get_transient_for (window) == NULL &&
+                          gtk_window_get_type_hint (window) == GDK_WINDOW_TYPE_HINT_NORMAL);
 
   tokens = g_strsplit (layout_desc, ":", 2);
   if (tokens)
@@ -352,7 +354,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
               AtkObject *accessible;
 
               if (strcmp (t[j], "icon") == 0 &&
-                  type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
+                  is_sovereign_window)
                 {
                   button = gtk_image_new ();
                   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
@@ -369,7 +371,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
                 }
               else if (strcmp (t[j], "menu") == 0 &&
                        menu != NULL &&
-                       type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
+                       is_sovereign_window)
                 {
                   button = gtk_menu_button_new ();
                   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
@@ -388,7 +390,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
                     gtk_image_set_from_icon_name (GTK_IMAGE (priv->titlebar_icon), "process-stop-symbolic", GTK_ICON_SIZE_MENU);
                 }
               else if (strcmp (t[j], "minimize") == 0 &&
-                       type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
+                       is_sovereign_window)
                 {
                   button = gtk_button_new ();
                   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
@@ -407,7 +409,7 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
                 }
               else if (strcmp (t[j], "maximize") == 0 &&
                        gtk_window_get_resizable (window) &&
-                       type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
+                       is_sovereign_window)
                 {
                   const gchar *icon_name;
                   gboolean maximized = gtk_window_is_maximized (window);
index 68dff16e759e4e29a83ba40e4c66873b740d6317..95beb5d761dc3db9b4f2be5334bb2963584beec3 100644 (file)
@@ -3059,6 +3059,8 @@ gtk_window_set_modal (GtkWindow *window,
        gtk_grab_remove (widget);
     }
 
+  update_window_buttons (window);
+
   g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_MODAL]);
 }
 
@@ -3311,6 +3313,8 @@ gtk_window_set_transient_for  (GtkWindow *window,
          priv->transient_parent_group = TRUE;
        }
     }
+
+  update_window_buttons (window);
 }
 
 /**